package com.whiteape.book.core.parser;

import com.whiteape.book.core.manager.ParserManager;
import com.whiteape.book.model.bo.ChapterContentBo;
import com.whiteape.book.model.dto.CollectionMediaBean;
import com.whiteape.book.model.dto.MediaChapterBean;
import com.whiteape.book.model.dto.SiteSourceBean;
import com.whiteape.book.utils.LogUtils;
import com.whiteape.book.utils.URLUtils;

import org.apache.commons.lang3.StringUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import io.reactivex.Single;

public class ChapterContentParser {


    public static Single<List<ChapterContentBo>> parseBook(SiteSourceBean siteSourceBean, String currentUrl, String html) {

        if (siteSourceBean == null || StringUtils.isEmpty(html)) {
            return Single.create(emitter -> emitter.onError(new Throwable("args check error")));
        }
        try {

            return Single.create(emitter -> {

                List<ChapterContentBo> result = new ArrayList<>();
//                Document doc = Jsoup.parse(html);
//                System.out.println(html);
                String contentListRule = siteSourceBean.getContentInfoRule().getContentList();
                String contentRule = siteSourceBean.getContentInfoRule().getContent();

                if (!StringUtils.isEmpty(contentListRule)) {
                    List list = ParserManager.getElementList(currentUrl, html, contentListRule);
//                    Elements list = doc.select(contentListRule);
                    if (list == null || list.size() == 0) {
                        emitter.onSuccess(result);
                        return;
                    }

                    int partNum = 0;
                    for (Object ele : list) {
                        String doc = ele.toString();
                        ChapterContentBo contentBo = new ChapterContentBo();
                        String content = ParserManager.parseOne(currentUrl, doc, contentRule, new HashMap<>());
                        contentBo.setContent(com.whiteape.book.utils.StringUtils.formatHtml(content));
//                        contentBo.setContent(content);
                        contentBo.setCurPartNum(partNum++);
                        contentBo.setPartTotal(list.size());
                        result.add(contentBo);
                    }
                } else {

//                    String content;
//                    if (contentRule.startsWith("$JS.")) {
//                        content = JsUtils.checkAndParseContent(contentRule, doc.html());
//                    } else {
//                        content = checkAndParse(doc.body(), contentRule);
//                    }
                    String content = ParserManager.parseOne(currentUrl, html, contentRule, new HashMap<>());
                    ChapterContentBo contentBo = new ChapterContentBo();
                    contentBo.setContent(com.whiteape.book.utils.StringUtils.formatHtml(content));
//                    contentBo.setContent(content);
                    result.add(contentBo);
                }
                emitter.onSuccess(result);

            });
        } catch (Exception e) {
            e.printStackTrace();
            return Single.create(emitter -> emitter.onError(new Throwable(e.getMessage())));
        }
    }


    /**
     * 漫画的主要问题是：1. 图片藏在js里面，那么需要content是$JS.的
     * 2. 一个章节对应多个page link，一个page link对应一张图
     *
     * @param siteSourceBean
     * @param
     * @param html
     * @return
     */
    public static Single<List<ChapterContentBo>> parseComic(SiteSourceBean siteSourceBean, CollectionMediaBean collectionMediaBean, MediaChapterBean chapter, String html) {
        if (siteSourceBean == null || StringUtils.isEmpty(html)) {
            return Single.create(emitter -> emitter.onError(new Throwable("args check error")));
        }
        String chapterId = chapter.getId();
        String chapterDetailUrl = chapter.getLink();

//        String chapterDetailUrl = mediaChapterBean.getLink();
//        String chapterId = mediaChapterBean.getId();

//        Document doc = Jsoup.parse(html);
//        System.out.println(html);
        //TODO 还有content分页情况
        List<ChapterContentBo> result = new ArrayList<>();
        String pageLinkListRule = siteSourceBean.getContentInfoRule().getPageLinkList();
        String pageTotalRule = siteSourceBean.getContentInfoRule().getPageTotal();

        int pageTotalTemp = -1;
        try {

            //如果是懒加载，这里的chapterDetailUrl 实际上是一个章节下具体的某一页的页面链接
            //那么只需要parseOnePageLink即可
//            if (lazy) {
//                return parseOnePageLink(html, chapterId, contentListRule, contentRule);
//            }
            if (!StringUtils.isEmpty(pageTotalRule)) {
//                pageTotalTemp = Integer.parseInt(JsoupSelectorEngine.checkAndParse(doc, pageTotalRule));
                pageTotalTemp = Integer.parseInt(ParserManager.parseOne(chapterDetailUrl, html, pageTotalRule, collectionMediaBean.getVarMap()));
            }
            final int pageTotal = pageTotalTemp;
            if (!StringUtils.isEmpty(pageLinkListRule)) {
                //如果pageLinkList不为空
//                if (pageLinkListRule.startsWith("@JS:")) {
                return Single.create(emitter -> {
                            try {
//                            List<String> linkList = JSEngine.checkAndParsePageLink(pageLinkListRule, chapterDetailUrl, doc.html(), pageTotal);
//                            List linkList = JSEngine.getElementList(chapterDetailUrl, doc.html(), pageLinkListRule, pageTotal);
                                List linkList = ParserManager.getElementList(chapterDetailUrl, html, pageLinkListRule, pageTotal, collectionMediaBean.getVarMap());
                                for (int i = 0; i < linkList.size(); i++) {
                                    ChapterContentBo bo = new ChapterContentBo();

                                    bo.setHeaders(siteSourceBean.getContentInfoRule().getHeaders());
//                                    bo.setReferer(URLUtils.getAbsolutePath(siteSourceBean.getSiteHostUrl(), chapterDetailUrl));
                                    bo.setChapterId(chapterId);
                                    bo.setPartTotal(linkList.size());
                                    bo.setLazyLoading(true);
                                    bo.setCurPartNum(i);
                                    // TODO check List return type
                                    bo.setContent(ParserManager.getElementString(linkList.get(i)));
                                    result.add(bo);
                                }
                                emitter.onSuccess(result);
                            } catch (Exception e) {
                                e.printStackTrace();
                                LogUtils.e("JS引擎解析出现错误，需要重试");
                                emitter.onError(e);
                            }


                        }
                );

//                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }


//        return parseOnePageLink(chapterDetailUrl, html, chapterId, contentListRule, contentRule);
        return parseOnePageLink(siteSourceBean, collectionMediaBean, chapter, html);

    }

    /**
     * 对于一般的MediaChapterBean，正常获取，非lazy,无curPartNum
     *
     * @param siteSourceBean
     * @param collectionMediaBean
     * @param chapter
     * @param html
     * @return
     */
    private static Single<List<ChapterContentBo>> parseOnePageLink(SiteSourceBean siteSourceBean, CollectionMediaBean collectionMediaBean, MediaChapterBean chapter, String html) {
//        return parseOnePageLink(curLink, html, chapterId, 0, contentListRule, contentRule);
        String curLink = chapter.getLink();
        String chapterId = chapter.getId();
        return parseOnePageLink(siteSourceBean, collectionMediaBean, chapterId, curLink, html, 0);
    }


    public static Single<List<ChapterContentBo>> parseOnePageLink(SiteSourceBean siteSourceBean, CollectionMediaBean collectionMediaBean, ChapterContentBo chapterBo, String html) {
        String curLink = chapterBo.getContent();
        String chapterId = chapterBo.getChapterId();
        int curPartNum = chapterBo.getCurPartNum();
        return parseOnePageLink(siteSourceBean, collectionMediaBean, chapterId, curLink, html, curPartNum);
    }

    public static Single<List<ChapterContentBo>> parseOnePageLinkLazy(SiteSourceBean siteSourceBean, CollectionMediaBean collectionMediaBean, ChapterContentBo chapterContentBo, String html) {
        return parseOnePageLink(siteSourceBean, collectionMediaBean, chapterContentBo, html);
    }


    /**
     * 每一个页面中，处理content
     *
     * @param html
     * @return
     */
    public static Single<List<ChapterContentBo>> parseOnePageLink(SiteSourceBean siteSourceBean, CollectionMediaBean collectionMediaBean, String chapterId, String curLink, String html, int curPartNum) {
        String contentListRule = siteSourceBean.getContentInfoRule().getContentList();
        String contentRule = siteSourceBean.getContentInfoRule().getContent();
//        Document doc = Jsoup.parse(html);

        List<ChapterContentBo> result = new ArrayList<>();
        Single<List<ChapterContentBo>> observable = Single.create(emitter -> {
            try {
                if (!StringUtils.isEmpty(contentListRule)) {
//                    Elements list = doc.select(contentListRule);
                    List list = ParserManager.getElementList(curLink, html, contentListRule,1, collectionMediaBean.getVarMap());
                    if (list == null || list.size() == 0) {
                        emitter.onSuccess(result);
//                        emitter.onComplete();
                        return;
                    }

                    int partNum = 0;
                    for (Object contentEle : list) {
                        ChapterContentBo contentBo = new ChapterContentBo();
//                        String content = checkAndParse(contentEle, contentRule);
                        String eleStr = ParserManager.getElementString(contentEle);
                        String content = ParserManager.parseOne(curLink, eleStr, contentRule, collectionMediaBean.getVarMap());
                        contentBo.setHeaders(siteSourceBean.getContentInfoRule().getHeaders());
//                        contentBo.setReferer(URLUtils.getAbsolutePath(siteSourceBean.getSiteHostUrl(), curLink));
                        contentBo.setChapterId(chapterId);
                        contentBo.setContent(content);
                        contentBo.setCurPartNum(partNum++);
                        contentBo.setLazyLoading(false);
                        contentBo.setPartTotal(list.size());
                        result.add(contentBo);
                    }
                } else {

                    String content;
//                    if (contentRule.startsWith("$JS.")) {
//
//                        content = JSEngine.checkAndParseContent(contentRule, doc.html());
//                    } else {
//
//                        content = checkAndParse(doc.body(), contentRule);
//                    }

                    content = ParserManager.parseOne(curLink, html, contentRule, collectionMediaBean.getVarMap());
                    String[] urls = content.split(",");
                    int partNum = curPartNum;
                    for (String url : urls) {
                        url = URLUtils.getAbsolutePath(curLink, url);
                        ChapterContentBo contentBo = new ChapterContentBo();
                        contentBo.setChapterId(chapterId);
                        contentBo.setHeaders(siteSourceBean.getContentInfoRule().getHeaders());
//                        contentBo.setReferer(URLUtils.getAbsolutePath(siteSourceBean.getSiteHostUrl(),curLink));
                        contentBo.setContent(url);
                        contentBo.setLazyLoading(false);
                        contentBo.setCurPartNum(partNum++);
                        contentBo.setPartTotal(urls.length);
                        result.add(contentBo);
                    }

                }


                emitter.onSuccess(result);
//                emitter.onComplete();

//            emitter.onComplete();
            } catch (Exception e) {
                e.printStackTrace();
                emitter.onError(e);
//                emitter.onComplete();
            }

        });

        return observable;

    }


}
